package es.upv.epsa.mobweb.moneyback;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Data;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.ObjectMapper;

import es.upv.epsa.mobweb.moneyback.adapters.TwoLinesListItemAdapter;
import es.upv.epsa.mobweb.moneyback.database.Contact;
import es.upv.epsa.mobweb.moneyback.json.JSONParser;

public class FriendsListActivity extends Activity {

	private Button 			btnUpdateFriends;
	private ListView 		list;
	private TextView 		txtVacia;

	private String			server_url;
	private JSONParser 		jsonParser;
	private ObjectMapper  	mapper 		= new ObjectMapper();

	private MainApplication app;

	ArrayList<String[]> 	allContacts = new ArrayList<String[]>();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.friends_list);

		jsonParser = new JSONParser();
		setWidgets();
		getDeviceContacts();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.friends_list, menu);
		return true;
	}

	private void setWidgets(){
		server_url				= getResources().getString(R.string.server_url) +
				getResources().getString(R.string.contacts_url);

		app						= (MainApplication) getApplication();

		btnUpdateFriends 		= (Button)	findViewById(R.id.btnUpdateFriends);
		list 					= (ListView) findViewById(R.id.list);
		txtVacia 				= (TextView) findViewById(R.id.txtVacia);

		btnUpdateFriends.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				new AlertDialog.Builder(FriendsListActivity.this)
				.setIcon(android.R.drawable.ic_dialog_alert)
				.setTitle("Update Friends")
				.setMessage("Are you sure you want to update your friends list?")
				.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
					@Override
					public void onClick(DialogInterface dialog, int which) {
						deleteServerContacts();
						updateServerContacts(allContacts);
					}

				})
				.setNegativeButton("No", null)
				.show();
			}

		});

		list.setOnItemClickListener(new OnItemClickListener(){

			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				String[] value = (String [])list.getItemAtPosition(position);

				// Check if it exists
				checkAccountWithFriend(value[1]);
			}

		});

	}

	private void checkAccountWithFriend(String mobile){
		JsonFactory 			jfactory 	= new JsonFactory();
		ByteArrayOutputStream 	bout 		= new ByteArrayOutputStream();
		JsonGenerator 			jGenerator;

		try {
			jGenerator = jfactory.createJsonGenerator(new OutputStreamWriter(bout, "UTF-8"));
			jGenerator.writeStartObject();

			jGenerator.writeStringField("action", "4");
			jGenerator.writeStringField("mobile", mobile);

			jGenerator.writeEndObject();
			jGenerator.close();

			new SendJSON("Getting contact information...", bout.toString(), true).execute();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void parseFriend(String json){
		try {
			JsonFactory jfactory = new JsonFactory();
			JsonParser jparser = jfactory.createJsonParser(json);
			Contact c = null;

			while(jparser.nextToken() == JsonToken.START_OBJECT){
				c = new Contact();
				c = mapper.readValue(jparser, Contact.class);
			}

			jparser.close();

			Intent intent = new Intent();
			intent.setClass(getApplicationContext(), AccountActivity.class);
			intent.putExtra("friend_id", String.valueOf(c.getId()));

			startActivity(intent);
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("all")
	private void getDeviceContacts(){
		String[] contacts 	= new String[] {Data._ID, Data.DISPLAY_NAME, Phone.NUMBER, Data.CONTACT_ID, Phone.TYPE, Phone.LABEL};
		Uri contentUri 		= Data.CONTENT_URI;
		Cursor cursor 		= this.getContentResolver().query(contentUri, 
				contacts, 
				Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'", 
				null, 
				Data.DISPLAY_NAME);
		allContacts.clear();
		if (cursor.moveToFirst()) {
			do {
				allContacts.add(
						new String[]{cursor.getString(cursor.getColumnIndex(Data.DISPLAY_NAME)), 
								cursor.getString(cursor.getColumnIndex(Phone.NUMBER))}
						);
			} while (cursor.moveToNext());
		}

		if(allContacts.size() == 0){
			list.setVisibility(View.GONE);
			txtVacia.setVisibility(View.VISIBLE);
		}

		TwoLinesListItemAdapter adapter = new TwoLinesListItemAdapter(this, allContacts);
		list.setAdapter(adapter);
	}

	private void deleteServerContacts(){
		JsonFactory 			jfactory 	= new JsonFactory();
		ByteArrayOutputStream 	bout 		= new ByteArrayOutputStream();
		JsonGenerator 			jGenerator;

		try {
			jGenerator = jfactory.createJsonGenerator(new OutputStreamWriter(bout, "UTF-8"));
			jGenerator.writeStartObject();

			jGenerator.writeStringField("action", "2");
			jGenerator.writeNumberField("user_id", app.getUser().getId());

			jGenerator.writeEndObject();
			jGenerator.close();

			new SendJSON("Deleting contacts from server...", bout.toString(), false).execute();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void updateServerContacts(ArrayList<String[]> contacts){
		JsonFactory 			jfactory 	= new JsonFactory();
		ByteArrayOutputStream 	bout 		= new ByteArrayOutputStream();
		JsonGenerator 			jGenerator;

		try {
			jGenerator = jfactory.createJsonGenerator(new OutputStreamWriter(bout, "UTF-8"));
			jGenerator.writeStartObject();

			jGenerator.writeStringField("action", "1");
			jGenerator.writeNumberField("user_id", app.getUser().getId());

			jGenerator.writeFieldName("contacts");
			jGenerator.writeStartArray();

			for(String[] s : contacts){
				jGenerator.writeStartObject();
				jGenerator.writeStringField("name", s[0]);
				jGenerator.writeStringField("mobile", s[1]);
				jGenerator.writeStringField("email", "");
				jGenerator.writeEndObject();
			}

			jGenerator.writeEndArray();
			jGenerator.writeEndObject();

			jGenerator.close();

			new SendJSON("Uploading contacts to server...", bout.toString(), true).execute();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private class SendJSON extends AsyncTask<Void, Void, Void>{
		String 			json 	= "";
		boolean 		parse 	= false;
		String 			data 	= "";
		String			msg 	= "";
		ProgressDialog 	dialog;

		public SendJSON(String msg, String json, boolean parse){
			this.json 	= json;
			this.parse 	= parse;
			this.msg 	= msg;
		}

		@Override
		protected Void doInBackground(Void... arg0) {
			data = jsonParser.sendJSON(server_url, json);

			return null;
		}

		@Override
		protected void onPreExecute(){
			dialog = ProgressDialog.show(FriendsListActivity.this, "", msg, true);
			dialog.setCancelable(false);
			dialog.setOnCancelListener(new OnCancelListener(){

				@Override
				public void onCancel(DialogInterface dialog) {

				}

			});
		}

		@Override
		protected void onPostExecute(Void result){
			if(parse){
				parseFriend(data);
			}

			dialog.dismiss();
		}
	}
}
